﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.IO;
using System.Globalization;
using GraffitiExtras.Plugins.Waegis.WaegisClient.Resources;

namespace GraffitiExtras.Plugins.Waegis.WaegisClient.Components
{
    /// <summary>
    /// Makes requests to the remote server to put the data and retrieve the repsonse
    /// </summary>
    internal class HttpClient
    {
        #region Public Methods

        /// <summary>
        /// Puts a request on the remote server
        /// </summary>
        /// <param name="url">The URL of the remote server</param>
        /// <param name="userAgent">The user agent for the request</param>
        /// <param name="timeout">Timeout in miliseconds</param>
        /// <param name="data">The data to be put on the server</param>
        /// <returns>Data returned from the remote server</returns>
        public virtual string PutRequest(Uri url, string userAgent, int timeout, string data)
        {
            return PutRequest(url, userAgent, timeout, data, null);
        }

        /// <summary>
        /// Puts a request on the remote server
        /// </summary>
        /// <param name="url">The URL of the remote server</param>
        /// <param name="userAgent">The user agent for the request</param>
        /// <param name="timeout">Timeout in miliseconds</param>
        /// <param name="data">The data to be put on the server</param>
        /// <param name="proxy">The proxy to be used for the request</param>
        /// <returns>Data returned from the remote server</returns>
        public virtual string PutRequest(Uri url, string userAgent, int timeout,
            string data, IWebProxy proxy)
        {
            if (data == null)
                throw new ArgumentNullException("data", Messages.ArgumentNull_String);

            ServicePointManager.Expect100Continue = false;
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

            Debug.Assert(request != null, "HttpWebRequest should not be null",
                string.Format("Calling WebRequest.Create(url) produced a null HttpWebRequest instance for the URL '{0}'", url));

            if (proxy != null)
                request.Proxy = proxy;

            request.UserAgent = userAgent;
            request.Timeout = timeout;
            request.Method = "PUT";

            UTF8Encoding encoding = new UTF8Encoding();
            byte[] bytes = encoding.GetBytes(data);
            request.ContentLength = bytes.Length;

            request.ContentType = "application/xml; charset=utf-8";
            request.KeepAlive = true;

            using (StreamWriter myWriter = new StreamWriter(request.GetRequestStream()))
            {
                myWriter.Write(data);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode < HttpStatusCode.OK && response.StatusCode >= HttpStatusCode.Ambiguous)
                throw new ResponseException(string.Format(CultureInfo.InvariantCulture,
                    Messages.InvalidResponse_Generic, response.StatusCode), response.StatusCode);

            string responseText;
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
            {
                responseText = reader.ReadToEnd();
            }

            return responseText;
        }

        #endregion
    }
}
